#include "headers_cpp.h"
#include "sha1.h"

#define NOT_FOUND "!NOT_FOUND"

int get_index_bf(char c)
{
	char alphabet[26];
	for(int i = 0; i < 26; i++) alphabet[i] = 'a' + i;
	int set_size = sizeof(alphabet);
	
	for(int i = 0; i < set_size; i++)
		if(alphabet[i] == c) return i;
	return -1;
}

string brute_force(int index, string hash)
{
	string pwd;
	char alphabet[26];
    for(int i = 0; i < 26; i++) alphabet[i] = 'a' + i;
	int set_size = sizeof(alphabet);
	
	int c1 = index;
	int c2 = 0;
	int c3 = 0;
	int c4 = 0;
	int c5 = 0;
	
	//	Task for when PW length < 5
	if(index == -1)
	{	// pwd length = 1
		pwd = " ";
		while(true)
		{
			pwd[0] = alphabet[c5];

			if(hash == sha1(pwd))
				return pwd;
			c5++;
			if(c5 == set_size)
			{
				c5 = 0;
				break;
			}
		}

		// pwd length = 2
		pwd = "  ";
		while(true)
		{
			pwd[0] = alphabet[c4];
			pwd[1] = alphabet[c5];

			if(hash == sha1(pwd))
				return pwd;
			c5++;
			if(c5 == set_size)
			{
				c5 = 0;
				c4++;
			}
			if(c4 == set_size)
			{
				c4 = 0;
				break;
			}
		}

		// pwd length = 3
		pwd = "   ";
		while(true)
		{
			pwd[0] = alphabet[c3];
			pwd[1] = alphabet[c4];
			pwd[2] = alphabet[c5];

			if(hash == sha1(pwd))
				return pwd;
			c5++;
			if(c5 == set_size)
			{
				c5 = 0;
				c4++;
			}
			if(c4 == set_size)
			{
				c4 = 0;
				c3++;
			}
			if(c3 == set_size)
			{
				c3 = 0;
				break;
			}
		}

		// pwd length = 4
		pwd = "    ";
		while(true)
		{
			pwd[0] = alphabet[c2];
			pwd[1] = alphabet[c3];
			pwd[2] = alphabet[c4];
			pwd[3] = alphabet[c5];

			if(hash == sha1(pwd))
				return pwd;
			c5++;
			if(c5 == set_size)
			{
				c5 = 0;
				c4++;
			}
			if(c4 == set_size)
			{
				c4 = 0;
				c3++;
			}
			if(c3 == set_size)
			{
				c3 = 0;
				c2++;
			}
			if(c2 == set_size)
			{
				c2 = 0;
				break;
			}
		}
	}

	else
	{
		pwd = "     ";
		while(true)
		{
			pwd[0] = alphabet[c1];
			pwd[1] = alphabet[c2];
			pwd[2] = alphabet[c3];
			pwd[3] = alphabet[c4];
			pwd[4] = alphabet[c5];
			
			if(hash == sha1(pwd))
				return pwd;
			
			c5++;
			if(c5 == set_size)
			{
				c5 = 0;
				c4++;
			}
			if(c4 == set_size)
			{
				c4 = 0;
				c3++;
			}
			if(c3 == set_size)
			{
				c3 = 0;
				c2++;
			}
			if(c2 == set_size)
			{
				c2 = 0;
				break;
			}
		}
	}

	return NOT_FOUND;
}

string brute_force(string start, string end, string hash)
{
	string result;
	if(start.length() < 5)
	{
		result = brute_force(-1, hash);
		if(result != NOT_FOUND) return result;
	}
	if(end.length() < 5) return NOT_FOUND;

	int ind_start = get_index_bf(start[0]);
	int ind_end	  = get_index_bf(end[0]);
	for(int i = ind_start; i <= ind_end; i++)
	{
		result = brute_force(i, hash);
		if(result != NOT_FOUND) return result;
	}
	return NOT_FOUND;
}

